package com.netscenery.yang.model;

import java.util.ArrayList;

import org.jdom2.Namespace;

public class Env {
	private ArrayList<MainModule> modules;
	private ArrayList<SubModule> subModules;
	private Module curModule;
	private Node curNode;
	private Grouping curGrouping;
	private Grouping refGrouping;
	private ArrayList<Typedef> derivedTypes;
	private ArrayList<Grouping> groupings;
	private ArrayList<DataDefElement> dataDefs;
	private ArrayList<String> prefixs;
	private ModelElement parent;
	private Object temp;
	private Namespace ns = Namespace.getNamespace("urn:ietf:params:xml:ns:yang:yin:1");;
	
	
	
	public Namespace getNs() {
		return ns;
	}
	public void setNs(Namespace ns) {
		this.ns = ns;
	}
	/**
	 * @return the curNode
	 */
	public Node getCurNode() {
		return curNode;
	}
	/**
	 * @param curNode the curNode to set
	 */
	public void setCurNode(Node curNode) {
		this.curNode = curNode;
	}
	/**
	 * @return the temp
	 */
	public Object getTemp() {
		return temp;
	}
	/**
	 * @param temp the temp to set
	 */
	public void setTemp(Object temp) {
		this.temp = temp;
	}
	
	public Grouping getCurGrouping() {
		return curGrouping;
	}
	public void setCurGrouping(Grouping curGrouping) {
		this.curGrouping = curGrouping;
	}
	public Grouping getRefGrouping() {
		return refGrouping;
	}
	public void setRefGrouping(Grouping refGrouping) {
		this.refGrouping = refGrouping;
	}
	/**
	 * ���ģ�����ȡģ��
	 * @param moduleName
	 * @return
	 */
	public Module getModule(String moduleName){
		
		return getModule(moduleName, null);
	}
	/**
	 * ���ģ�����ȡģ��
	 * @param moduleName
	 * @return
	 */
	public Module getModule(String moduleName,String revisionDate){
		if (null == moduleName){
			return null;
		}
		
		
		if (null == modules && null == subModules){
			return null;
		}
		
		int modulesSize = 0;
		int subModulesSize = 0;
		if (null != modules){
			modulesSize = modules.size();
		}
		
		if (null != subModules){
			subModulesSize = subModules.size();
		}
		int searchedCount = 0;
		int searchedPos = 0;
		//����ģ���б�����
		for (int i = 0; i < modulesSize;i++){
			MainModule module = modules.get(i);
			if (null != module){
				if(module.getName().equals(moduleName)){
					if (null != revisionDate){
						if (revisionDate.equals(module.getCurRevisionDate())){
							return module;
						}
					}
					else {
						searchedCount++;
						searchedPos = i;
					}
				}
			}
		}
		if (0 != searchedCount){
			if (1== searchedCount){
				return modules.get(searchedPos);
			}
			else {
				return null;
			}
		}
		searchedCount = 0;
		searchedPos = 0;
		//����Ҳ�����������ģ���б���ȥ��
		for (int i = 0; i < subModulesSize; i++){
			SubModule module = subModules.get(i);
			if (null != module){
				if(module.getName().equals(moduleName)){
					if (null != revisionDate){
						if (revisionDate.equals(module.getCurRevisionDate())){
							return module;
						}
					}
					else {
						searchedCount++;
						searchedPos = i;
					}
				}
			}
		}
		if (0 != searchedCount){
			if (1== searchedCount){
				return modules.get(searchedPos);
			}
			else {
				return null;
			}
		}
		return null;
	}

	/**
	 * ��ģ���б������һ��ģ��
	 * @param module
	 * @return
	 */
	public boolean addMainModule(MainModule module){
		if (null == module){
			return false;
		}
		

		
		Module m = getModule(module.getName(),module.getCurRevisionDate());
		if (null != m){
			return false;
		}
		if (null == modules){
			modules = new ArrayList<MainModule> (1);
		}
		
		modules.add(module);
		return true;
	}
	/**
	 * ����ģ���б������һ����ģ��
	 * @param module
	 * @return
	 */
	public boolean addSubModule(SubModule module){
		if (null == module){
			return false;
		}
		

		
		Module m = getModule(module.getName(),module.getCurRevisionDate());
		if (null != m){
			return false;
		}
		if (null == subModules){
			subModules = new ArrayList<SubModule>(1);
		}
		subModules.add(module);
		return true;
	}
	
	/**
	 * @return the curModule
	 */
	public Module getCurModule() {
		return curModule;
	}
	/**
	 * @param curModule the curModule to set
	 */
	public void setCurModule(Module curModule) {
		this.curModule = curModule;
	}
	public int getDerivedTypesNumber(){
		if (null == derivedTypes){
			return 0;
		}
		
		return derivedTypes.size();
	}
	
	public Typedef getDerivedType(int index){
		if (null == derivedTypes){
			return null;
		}
		
		return derivedTypes.get(index);
	}
	public Typedef getDerivedType(String name){
		if (null == name){
			return null;
		}
		
		if (null == derivedTypes){
			return null;
		}
		
		int size = derivedTypes.size();
		
		for (int i = 0; i < size; i++){
			Typedef def = derivedTypes.get(i);
			if (null != def){
				if (def.getName().equals(name)){
					return def;
				}
			}
		}
		
		return null;
	}
	
	public boolean addDerivedType(Typedef def){
		
		if (null == def){
			return false;
		}
		
		Typedef d = this.getDerivedType(def.getName());
		if (null != d){
			return false;
		}
		if (null == this.derivedTypes){
			derivedTypes = new ArrayList<Typedef>(1);
		}
		this.derivedTypes.add(def);
		return true;
	}
	
	public Typedef removeDerivedType(String name){
		if (null == name){
			return null;
		}
		if (null == derivedTypes){
			return null;
		}
		
		int size = derivedTypes.size();
		
		for (int i = 0; i < size; i++){
			Typedef def = derivedTypes.get(i);
			if (null != def){
				if (def.getName().equals(name)){
					return derivedTypes.remove(i);
				}
			}
		}
		
		return null;
	}
	public Typedef removeDerivedType(int index){
		if (null == derivedTypes){
			return null;
		}
		
		return derivedTypes.remove(index);
	}
	
	
	public int getGroupingsNumber(){
		if (null == groupings){
			return 0;
		}
		
		return groupings.size();
	}
	
	public Grouping getGrouping(int index){
		if (null == groupings){
			return null;
		}
		
		return groupings.get(index);
	}
	public Grouping getGrouping(String name){
		if (null == name){
			return null;
		}
		
		if (null == groupings){
			return null;
		}
		
		int size = groupings.size();
		
		for (int i = 0; i < size; i++){
			Grouping def = groupings.get(i);
			if (null != def){
				if (def.getName().equals(name)){
					return def;
				}
			}
		}
		
		return null;
	}
	
	public boolean addGrouping(Grouping def){
		
		if (null == def){
			return false;
		}
		
		Grouping d = this.getGrouping(def.getName());
		if (null != d){
			return false;
		}
		if (null == this.groupings){
			groupings = new ArrayList<Grouping>(1);
		}
		this.groupings.add(def);
		return true;
	}
	
	public Grouping removeGrouping(String name){
		if (null == name){
			return null;
		}
		if (null == groupings){
			return null;
		}
		
		int size = groupings.size();
		
		for (int i = 0; i < size; i++){
			Grouping def = groupings.get(i);
			if (null != def){
				if (def.getName().equals(name)){
					return groupings.remove(i);
				}
			}
		}
		
		return null;
	}
	public Grouping removeGrouping(int index){
		if (null == groupings){
			return null;
		}
		
		return groupings.remove(index);
	}
	
	public SubModule removeSubModule(String name){
		if (null == name){
			return null;
		}
		if (null == this.subModules){
			return null;
		}
		
		int size = subModules.size();
		
		for (int i = 0; i < size; i++){
			SubModule sm = subModules.get(i);
			if (null != sm){
				if (sm.getName().equals(name)){
					return subModules.remove(i);
				}
			}
		}
		
		return null;
	}
	
	public MainModule removeMainModule(String name){
		if (null == name){
			return null;
		}
		if (null == this.modules){
			return null;
		}
		
		int size = modules.size();
		
		for (int i = 0; i < size; i++){
			MainModule sm = modules.get(i);
			if (null != sm){
				if (sm.getName().equals(name)){
					return modules.remove(i);
				}
			}
		}
		
		return null;
	}
	public DataDefElement getDataDef(String name){
		if (null == name){
			return null;
		}
		
		if (null == dataDefs){
			return null;
		}
		
		int size = dataDefs.size();
		
		for (int i = 0; i < size; i++){
			DataDefElement n = dataDefs.get(i);
			if (null != n){
				if (n.getName().equals(name)){
					return n;
				}
			}
		}
		
		return null;
	}
	
	public boolean addDataDef(DataDefElement node){
		
		if (null == node){
			return false;
		}
		
		DataDefElement n = this.getDataDef(node.getName());
		if (null != n){
			return false;
		}
		if (null == this.dataDefs){
			dataDefs = new ArrayList<DataDefElement>(1);
		}
		this.dataDefs.add(node);
		return true;
	}
	
	public DataDefElement removeDataDef(String name){
		if (null == name){
			return null;
		}
		if (null == dataDefs){
			return null;
		}
		
		int size = dataDefs.size();
		
		for (int i = 0; i < size; i++){
			DataDefElement n = dataDefs.get(i);
			if (null != n){
				if (n.getName().equals(name)){
					return dataDefs.remove(i);
				}
			}
		}
		
		return null;
	}
	
	/**
	 * @return the parent
	 */
	public ModelElement getParent() {
		return parent;
	}
	/**
	 * @param parent the parent to set
	 */
	public void setParent(ModelElement parent) {
		this.parent = parent;
	}
	
	public boolean hasPrefix(String prefix){
		if (null == prefix){
			return false;
		}
		
		if (null == prefixs){
			return false;
		}
		
		int size = prefixs.size();
		
		for (int i = 0; i < size; i++){
			String  p = prefixs.get(i);
			if (null != p){
				if (p.equals(prefix)){
					return true;
				}
			}
		}
		
		return false;
	}
	
	public boolean addPrefix(String prefix){
		
		if (null == prefix){
			return false;
		}
		
		if (hasPrefix(prefix)){
			return false;
		}
		
		if (null == this.prefixs){
			prefixs = new ArrayList<String>(1);
		}
		this.prefixs.add(prefix);
		return true;
	}
	
	public void removePrefix(String prefix){
		if (null == prefix){
			return;
		}
		if (null == prefixs){
			return ;
		}
		
		int size = prefixs.size();
		
		for (int i = 0; i < size; i++){
			String p = prefixs.get(i);
			if (null != p){
				if (p.equals(prefix)){
					prefixs.remove(i);
					return;
				}
			}
		}
		
		return;
	}
	
	
	public Env clone(){
		Env env = new Env();
		env.curModule = this.curModule;
		env.curNode = this.curNode;
		env.curGrouping = this.curGrouping;
		env.refGrouping = this.refGrouping;
		if (null != this.modules){
			env.modules = new ArrayList<MainModule> (1);
			for (int i = 0; i < this.modules.size();i++){
				MainModule sm = this.modules.get(i);
				if (null != sm){
					env.modules.add(sm);
				}
			}
		}
		
		if (null != this.subModules){
			env.subModules = new ArrayList<SubModule> (1);
			for (int i = 0; i < this.subModules.size();i++){
				SubModule sm = this.subModules.get(i);
				if (null != sm){
					env.subModules.add(sm);
				}
			}
		}
		
		if (null != this.derivedTypes){
			env.derivedTypes = new ArrayList<Typedef> (1);
			for (int i = 0; i < this.derivedTypes.size();i++){
				Typedef sm = this.derivedTypes.get(i);
				if (null != sm){
					env.derivedTypes.add(sm);
				}
			}
		}
		if (null != this.groupings){
			env.groupings = new ArrayList<Grouping> (1);
			for (int i = 0; i < this.groupings.size();i++){
				Grouping sm = this.groupings.get(i);
				if (null != sm){
					env.groupings.add(sm);
				}
			}
		}
		if (null != this.prefixs){
			env.prefixs = new ArrayList<String> (1);
			for (int i = 0; i < this.prefixs.size();i++){
				String sm = this.prefixs.get(i);
				if (null != sm){
					env.prefixs.add(sm);
				}
			}
		}		
		env.parent = this.parent;
		
		return env;
	}
	
	public Env cloneExtra(){
		Env env = new Env();
		if (null != this.modules){
			env.modules = new ArrayList<MainModule> (1);
			for (int i = 0; i < this.modules.size();i++){
				MainModule sm = this.modules.get(i);
				if (null != sm){
					env.modules.add(sm);
				}
			}
		}
		
		if (null != this.subModules){
			env.subModules = new ArrayList<SubModule> (1);
			for (int i = 0; i < this.subModules.size();i++){
				SubModule sm = this.subModules.get(i);
				if (null != sm){
					env.subModules.add(sm);
				}
			}
		}
			
		return env;
	}
	/**
	 * @return the modules
	 */
	public ArrayList<MainModule> getModules() {
		return modules;
	}

	/**
	 * @return the subModules
	 */
	public ArrayList<SubModule> getSubModules() {
		return subModules;
	}
	
	
	
}
